#include <system.h>
#include <std.h>
#include <fdc.h>
#include <pio.h>
#include <error.h>
#include <type.h>
#include <memory.h>
#include <dint.h>
#include <keyboard.h>
#include <sched.h>
#include <asm.h>
#include <text.h>
#include <irq.h>
#include <ui.h>
#include <ksetting.h>
#include <biosdisk.h>

#define MAX_OBJ 20
#define MAX_DAT 20
#define MAX_LINK 20
#define MAX_DESC 32
#define MAX_DT 20

#define CRPS_STACK 100



/*DTreg imports:*/
void list_dt_reg();
void init_dt_reg();

/*Stack data structure*/
unsigned long *stack;
unsigned top;

void init_stack(unsigned size)
{
	stack=(unsigned long *)malloc(size*sizeof(unsigned long));
	top=NULL;
}

void push(unsigned long val)
{
	stack[top++]=val;
}

unsigned long pop()
{
	return stack[--top];
}

/*General data descriptor for arrays declared by user
*/

#define DT_INT 0
#define DT_STRING 1

/*d_type defines the data type. The data is stored in the 'data' pointer.
d_len specifies the total length of the array
next specifies the next data declaration made by the user
child specifies the child data structure of the current structure. Child is implemented in order
	to declare structures within an object
*/

struct data	{
	int d_type;
	unsigned d_len;
	void *x,*con;	/*Constructor data. This data is just an image of x and is created when the user initializes the data*/
	struct data *next,*child;
};

void init_object_data(struct data *x)
{
	memset(x,NULL,sizeof(struct data));
}

/*Data description table
This includes the data physical address and its corresponding name for the user*/


/*Possible link types:*/
#define LT_NC 0	//Unconditional link. Link without checking any condition
#define LT_C 1 //Conditional link
#define LT_SEQ 0	//Sequential link
#define LT_CONC 0x10
#define LT_DEAD 0x20	//Dead link... Just to keep the object in memory and not execute it
#define LT_CONST 0x100	//c_var2 is actually a constant, so compare c_var1 with c_var2(const).
/*For concurrent link a new control is created that executes the link with other links and when the link
returns the control is ended.*/

/*A link which specifies a condition which if satisfied, the link is taken.*/

/*Possible condition types:*/
#define CON_E 0	//Equal
#define CON_G 1	//Greater
#define CON_L 2	//Less
#define CON_GE 3
#define CON_LE 4

struct object;


/*The linkpass data link
Data is passed to an object through a link with data_lp.
*/

struct data_lp	{
	struct data *passed_data;
	struct data_lp *next;
};

struct link	{
	struct object *link_object;
	struct data *c_dat1,*c_dat2;	//Data on which condition is to be tested.
	int c_type;	//Condition type
	int link_type;
	struct data_lp *linkpass;	/*linkpass is a linked list of data that is passed from current object to the linked object through the link*/
};

/*The main object structure.
It includes a function for core objects which is written in C and linked during initialization before the rt system
starts up.
*/
/*var points to the first data declaration*/
struct object	{
	void (*fn)(struct object *this_obj);
	struct link *links[MAX_LINK];
	struct data *var;
	struct data_lp *linkpass;	/*linkpass here in the object is the data that was passed to this object by the object that linked to it.*/
};

/*The links holds pointers to link structures allocated at runtime.
When a new link is created a link pointer in the array which is initialized as null is now allocated to hold a new link structure.*/
static struct data_desctable	{
	struct object *holder;	/*This is the object that holds this data structure*/
	struct data *x;
	char desc[MAX_DESC];
}data_desc[MAX_DAT];


/*Object description table
This includes the object physical address and its corresponding name for the user*/
static struct obj_desctable	{
	struct object *x;
	char desc[MAX_DESC];
}obj_desc[MAX_OBJ];

/*Object and data registry issues:
The object and data registry has been separately created. Earlier the object and data structures
themselves included their names. This system was scrapped and a separate registry is now maintained.
The main goal to make such a system is to be able to remove the object and data names and let the system execute.
This allows software developers to protect the inner architecture of the program. When a program is fully
made then the software developer may remove the names associated with the program from the registry for
security. This makes the program architecture invisible to the client.
*/

/*Registers a data in the descriptor table with name 'name'*/
void register_data(struct data *x,struct object *h,char *name)
{
	int i;
	for(i=NULL;i<MAX_DAT && data_desc[i].x;i++);
	data_desc[i].x=x;
	data_desc[i].holder=h;
	strcpy(data_desc[i].desc,name);
}

/*Deletes an entry in the table*/
void unregister_data(struct data *x)
{
	int i;
	for(i=NULL;i<MAX_DAT;i++)	{
		if(data_desc[i].x==x)	{
			data_desc[i].x=NULL;
			break;
		}
	}
}

/*This gets the descriptor for the object requested. **Needs hashing.*/
char *get_data_desc(struct data *x)
{
	int i;
	for(i=NULL;i<MAX_DAT;i++)	{
		if(data_desc[i].x==x)
			return data_desc[i].desc;
	}
	return NULL;
}

/*This gets the data for the descriptor requested. **Needs hashing.*/
struct data *get_data(char *desc)
{
	int i;
	for(i=NULL;i<MAX_DAT;i++)	{
		if(!strcmp(data_desc[i].desc,desc))
			return data_desc[i].x;
	}
	return NULL;
}

/*Make all null entries in the object descriptor table*/
void init_data_desc()
{
	memset(data_desc,NULL,sizeof(struct data_desctable)*MAX_DAT);
}

struct data *create_data(struct object *x)
{
	/*First traverse to the last data structure using the next link*/
	struct data *t;
	if(!(x->var))	{
		x->var=(struct data *)malloc(sizeof(struct data));
		init_object_data(x->var);
		return x->var;
	}
	for(t=(x->var);t->next;t=t->next);
	t->next=(struct data *)malloc(sizeof(struct data));
	t=t->next;
	init_object_data(t);
	return t;
}

/*This function adds a child to the specified parent data structure*/
struct data *create_child_data(struct data *x)
{
	struct data *t;
	if(!(x->child))	{
		x->child=(struct data *)malloc(sizeof(struct data));
		init_object_data(x->child);
		return x->child;
	}
	for(t=(x->child);t->next;t=t->next);
	t->next=(struct data *)malloc(sizeof(struct data));
	t=t->next;
	init_object_data(t);
	return t;
}

/*Registers an object in the descriptor table with name 'name'*/
void register_object(struct object *x,char *name)
{
	int i;
	for(i=NULL;i<MAX_OBJ && obj_desc[i].x;i++);
	obj_desc[i].x=x;
	strcpy(obj_desc[i].desc,name);
}

/*Deletes an entry in the table*/
void unregister_object(struct object *x)
{
	int i;
	for(i=NULL;i<MAX_OBJ;i++)	{
		if(obj_desc[i].x==x)	{
			obj_desc[i].x=NULL;
			break;
		}
	}
}
	
/*This gets the descriptor for the object requested. **Needs hashing.*/
char *get_obj_desc(struct object *x)
{
	int i;
	for(i=NULL;i<MAX_OBJ;i++)	{
		if(obj_desc[i].x==x)
			return obj_desc[i].desc;
	}
	return NULL;
}

struct object *get_object(char *desc)
{
	int i;
	for(i=NULL;i<MAX_OBJ;i++)	{
		if(!strcmp(obj_desc[i].desc,desc))
			return obj_desc[i].x;
	}
	return NULL;
}

/*Make all null entries in the object descriptor table*/
void init_obj_desc()
{
	memset(obj_desc,NULL,sizeof(struct obj_desctable)*MAX_OBJ);
}

/*Initiate members of and object, make pointers null*/
void init_object(struct object *x)
{
	memset(x,NULL,sizeof(struct object));
}

/*Construct the link structure*/
void init_object_link(struct link *x)
{
	memset(x,NULL,sizeof(struct link));
}

/*Create a new object and construct the members*/
struct object *create_object()
{
	struct object *x;
	x=(struct object *)malloc(sizeof(struct object));
	init_object(x);
	return x;
}

/*Creates a new link*/
struct link *create_link()
{
	struct link *x;
	x=(struct link *)malloc(sizeof(struct object));
	init_object_link(x);
	return x;
}

int get_free_link(struct object *x);
/*This function is used to add lib functions.. They don't execute from the parent object. Hence a dead link*/
void create_dead_link(struct object *to,struct object *x)
{
	int i;
	to->links[i=get_free_link(to)]=(struct link *)malloc(sizeof(struct object));
	init_object_link(to->links[i]);
	to->links[i]->link_object=x;
	to->links[i]->link_type|=LT_DEAD;
}

void delete_link(struct object *of,int linkno)
{
	free(of->links[linkno]);
	of->links[linkno]=NULL;
}

int get_free_link(struct object *x)
{
	int i;
	for(i=NULL;i<MAX_LINK;i++)	{
		if(!(x->links[i]))
			return i;
	}
}

/*Console output functions:
First parameter passed is the parameter to be printed on the console*/

void consolech_out(struct object *this_obj)
{
	printk("%c",this_obj->linkpass->passed_data->x);
}

void consolestr_out(struct object *this_obj)
{
	printk("%s",this_obj->linkpass->passed_data->x);
}

void consolenum_out(struct object *this_obj)
{
	printk("%d",this_obj->linkpass->passed_data->x);
}

void inc(struct object *this_obj)
{
	(this_obj->linkpass->passed_data->x)++;
}

void dec(struct object *this_obj)
{
	(this_obj->linkpass->passed_data->x)--;
}

/*Basic arithmetic objects:
For these objects there are two parameters
a=a+b
a and b are passed in sequence with a passed as the first data_lp and b as the second.
*/

void add(struct object *this_obj)
{
	unsigned long x;
	x=(unsigned long)this_obj->linkpass->passed_data->x;
	x+=(unsigned long)(this_obj->linkpass->next->passed_data->x);
	this_obj->linkpass->passed_data->x=(void *)x;
}

void sub(struct object *this_obj)
{
	unsigned long x;
	x=(unsigned long)this_obj->linkpass->passed_data->x;
	x-=(unsigned long)(this_obj->linkpass->next->passed_data->x);
	this_obj->linkpass->passed_data->x=(void *)x;
}

void mul(struct object *this_obj)
{
	unsigned long x;
	x=(unsigned long)this_obj->linkpass->passed_data->x;
	x*=(unsigned long)(this_obj->linkpass->next->passed_data->x);
	this_obj->linkpass->passed_data->x=(void *)x;
}

void div(struct object *this_obj)
{
	unsigned long x;
	x=(unsigned long)this_obj->linkpass->passed_data->x;
	x/=(unsigned long)(this_obj->linkpass->next->passed_data->x);
	this_obj->linkpass->passed_data->x=(void *)x;
}

/*Port output functions*/
void portout(struct object *this_obj)
{
	outb((u16)(this_obj->linkpass->passed_data->x),(u16)(this_obj->linkpass->next->passed_data->x));
}

void portin(struct object *this_obj)
{
	this_obj->linkpass->next->passed_data->x=(void *)(inb((u16)(this_obj->linkpass->passed_data->x)));
}

/*Object at which an execution line (The whole system does not stop) stops. This object
performs the required cleanup.*/

struct object *systop;

/*Initiates the initial system with the sys object and the core objects.
Returns the sys pointer*/
struct object *init_sys()
{
	struct object *x,*conch,*constr,*incobj,*decobj;
	init_data_desc();
	init_obj_desc();
	x=create_object();
	conch=create_object();
	conch->fn=consolech_out;
	constr=create_object();
	constr->fn=consolestr_out;
	incobj=create_object();
	incobj->fn=inc;
	decobj=create_object();
	decobj->fn=dec;
	systop=create_object();
	struct object *addo,*subo,*mulo,*divo,*outo,*ino;
	addo=create_object();
	subo=create_object();
	mulo=create_object();
	divo=create_object();
	outo=create_object();
	ino=create_object();
	addo->fn=add;
	subo->fn=sub;
	mulo->fn=mul;
	divo->fn=div;
	outo->fn=portout;
	ino->fn=portin;
	struct object *consolenum;
	consolenum=create_object();
	consolenum->fn=consolenum_out;
	register_object(consolenum,"consolenum");
	register_object(addo,"add");
	register_object(subo,"sub");
	register_object(mulo,"mul");
	register_object(divo,"div");
	register_object(outo,"portout");
	register_object(ino,"portin");
	/*sys object is the main object to which control is passed*/
	register_object(systop,"stop");
	register_object(x,"sys");
	register_object(conch,"consolech");
	register_object(constr,"consolestr");
	register_object(incobj,"inc");
	register_object(decobj,"dec");
	struct object *lib;	/*The library in which the above core functions will be listed*/
	lib=create_object();
	register_object(lib,"lib");
	create_dead_link(lib,incobj);
	create_dead_link(lib,decobj);
	create_dead_link(lib,addo);
	create_dead_link(lib,subo);
	create_dead_link(lib,mulo);
	create_dead_link(lib,divo);
	create_dead_link(lib,systop);
	create_dead_link(lib,consolenum);
	create_dead_link(lib,conch);
	create_dead_link(lib,constr);
	create_dead_link(lib,outo);
	create_dead_link(lib,ino);
	init_stack(CRPS_STACK);
	return x;
}

/*This function is to be used during creation time. This function creates the constructor of the initialized data*/
/*The constructor is later used to reconstruct the data when control is passed to the object*/
int make_constructor(struct data *d)
{
	memcpy(d->con,d->x,d->d_len);
	return NULL;
}

int reconstruct(struct data *d)
{
	memcpy(d->x,d->con,d->d_len);
	return NULL;
}

/*Pass a data through a link
This function is called at runtime when the user
adds data structures to be passed through the link to the linked object
The data structure d is added to the link x and passed to the destination object*/

int make_linkpass(struct link *x,struct data *d)
{
	struct data_lp *t;
	struct data_lp *new_data_lp;
	new_data_lp=(struct data_lp *)malloc(sizeof(struct data_lp));
	new_data_lp->passed_data=d;
	new_data_lp->next=NULL;
	if(!(x->linkpass))	{
		x->linkpass=new_data_lp;
		return NULL;
	}
	for(t=x->linkpass;t->next;t=t->next);
	t->next=new_data_lp;
	return NULL;
}

/*Execution system for RPS*/

#define VERR 3

/*Function that compares two data structures*/
int compare(struct data *d1,struct data *d2)
{
	if(d1->d_type==DT_INT && d1->d_type==DT_INT)	{
		if((d1->x)==(d2->x))
			return CON_E;
		else if((d1->x)>(d2->x))
			return CON_G;
		else if((d1->x)<(d2->x))
			return CON_L;
	} else
		return VERR;
}

int compare_const(struct data *d1,struct data *d2)
{
	if(d1->d_type==DT_INT)	{
		if((d1->x)==d2)
			return CON_E;
		else if((d1->x)>(void *)d2)
			return CON_G;
		else if((d1->x)<(void *)d2)
			return CON_L;
	} else
		return VERR;
}

void terminate();

/*This function is added as a thread to the host operating system. For concurrent links this function threads.*/
	

void control_rps(struct object *main)
{
	int i,cres,linked;
	struct link *cur_link;
	//printk("[%s]",get_obj_desc(main));
	if(main==systop)
		terminate();
	if(main->fn)
		main->fn(main);
	lagain:
	linked=0;	/*Maintain a flag that will tell us that we found a link in the set of links*/
	for(i=NULL;i<MAX_LINK;i++)	{
		cur_link=main->links[i];
		if(cur_link)	{
			if((cur_link->link_type)&LT_C)	{	//Conditional link
				if((cur_link->link_type)&LT_CONST)	//c_dat2 is a constant
					cres=compare_const(cur_link->c_dat1,cur_link->c_dat2);
				else
					cres=compare(cur_link->c_dat1,cur_link->c_dat2);
				switch(cur_link->c_type)	{
					case CON_E:	if(cres==CON_E)	{
									cur_link->link_object->linkpass=cur_link->linkpass;
									//printk("[lto:%s]",get_obj_desc(cur_link->link_object));
									linked=1;
									control_rps(cur_link->link_object);
								}
								break;
					case CON_G:	if(cres==CON_G)	{
									cur_link->link_object->linkpass=cur_link->linkpass;
									//printk("[lto:%s]",get_obj_desc(cur_link->link_object));
									linked=1;
									control_rps(cur_link->link_object);
								}
								break;
					case CON_L:	if(cres==CON_L)	{
									cur_link->link_object->linkpass=cur_link->linkpass;
									//printk("[lto:%s]",get_obj_desc(cur_link->link_object));
									linked=1;
									control_rps(cur_link->link_object);
								}
								break;
					case CON_GE:	if(cres==CON_G || cres==CON_E)	{
									cur_link->link_object->linkpass=cur_link->linkpass;
									//printk("[lto:%s]",get_obj_desc(cur_link->link_object));
									linked=1;
									control_rps(cur_link->link_object);
								}
								break;
					case CON_LE:	if(cres==CON_L || cres==CON_E)	{
									cur_link->link_object->linkpass=cur_link->linkpass;
									//printk("[lto:%s]",get_obj_desc(cur_link->link_object));
									linked=1;
									control_rps(cur_link->link_object);
								}
								break;
				}/*For conditional links always check whether the condition is not satisfied and only then goto the next link*/
			} else	{
				cur_link->link_object->linkpass=cur_link->linkpass;
				//printk("[lto:%s]",get_obj_desc(cur_link->link_object));
				if((cur_link->link_type) & LT_CONC)	{
					create_thread("control_rps",control_rps,cur_link->link_object,NULL);
				} else if((cur_link->link_type) & LT_DEAD)	{
				} else
					control_rps(cur_link->link_object);
			}
		} else
			break;
	}
	if(linked)
		goto lagain;
}

/*RPS editing system based on the shell*/

struct object *cur,*x;
struct data *d,*cur_data=NULL;
struct link *cur_link=NULL;
int i;

void cmd_link(struct param_list *params)
{
	if(!(x=get_object(params->string)))	{
		printk("\nObject not found.");
	}
	cur->links[i=get_free_link(cur)]=create_link();
	cur->links[i]->link_object=x;
	cur_link=cur->links[i];
}

void cmd_link_open(struct param_list *params)
{
	for(i=0;i<MAX_LINK && cur->links[i];i++)	{
		if(!strcmp(params->string,get_obj_desc(cur->links[i]->link_object)))	{
			cur_link=cur->links[i];
			break;
		}
	}
}

void init_rpsvm_commands()
{
	register_cmd("link",cmd_link,1,"Make a new link to the current object");
	register_cmd("link_open",cmd_link_open,1,"Open a link for editing");
}

/*-------------------------Object display functions & user interface: OS dependent frontend--------------------*/

#define USR_INP 256
#define ERROR -1

char *LTC_usr[]={"NoCondition","Condition"};
char *LTT_usr[]={"seq","conc","dead"};
char *CON_usr[]={"=",">","<",">=","<="};
char *LT_usr_inp[]={"-","|","."};	//Sequential,Concurrent and Dead link representations at commandline

#define CON_CNT 5
#define LT_CNT 3

void terminate()
{
	delete_thread(running_thread_id());
}


/*Recursive function to show child data structures also*/

int rec=0;
int show_data(struct data *d)
{
	int i;
	char *desc;
	rec++;
	for(;d;d=d->next)	{
		if(!(desc=get_data_desc(d)))	{
			printk("Data not found");
			continue;
		}
		printk("\n");
		i=rec;
		while((i--)>0)
			printk("-");	/*Hyphens displayed show the depth of the data structure*/
		printk("%s",desc);
		if(d->d_type==DT_STRING)	{
			printk(" %s",d->x);
		} else	{
			printk(" %d",d->x);
		}
		if(d->child)
			show_data(d->child);
	}
	rec--;
	return NULL;
}

/*Displays the contents of an object in detail*/
int display_object(struct object *x)
{
	char *desc;
	struct data_lp *t;
	int i;
	printk("\n{");
	if(!(desc=get_obj_desc(x)))	{	/*Get the object descriptor from the table*/
		printk("\nObject not found/not registered");
		return ERROR;
	}
	printk("%s",desc);
	for(i=NULL;i<MAX_LINK;i++)	{
		if(x->links[i])	{
			if(!(desc=get_obj_desc(x->links[i]->link_object)))	{	/*Find the descriptor of the object that this object is linking to*/
				printk("\n-Link object not found");
				continue;
			}
			printk("\n-%s %s,%s",desc,LTC_usr[x->links[i]->link_type & 1],LTT_usr[(x->links[i]->link_type & 0x70)>>4]);				
			printk(" on %s %s ",get_data_desc(x->links[i]->c_dat1),CON_usr[x->links[i]->c_type]);
			if((x->links[i]->link_type)&LT_CONST)
				printk("%d",x->links[i]->c_dat2);
			else
				printk("%s",get_data_desc(x->links[i]->c_dat2));
			printk("(");
			for(t=x->links[i]->linkpass;t;t=t->next)	{
				printk(" %s",get_data_desc(t->passed_data));
			}
			printk(")");
		}
	}
	rec=0;
	show_data(x->var);
	printk("}");
	return NULL;
}

/*List display functions to simply display the names of the objects registered*/
int display_list()
{
	int i;
	for(i=NULL;i<MAX_OBJ;i++)	{
		if(obj_desc[i].x)
			printk("\n%s",obj_desc[i].desc);
	}
}

int display_vlist()
{
	int i;
	for(i=NULL;i<MAX_DAT;i++)	{
		if(data_desc[i].x)
			printk("\n%s",data_desc[i].desc);
	}
}

/*Main commandline interface*/


kdrv *disk;


struct timer_call test_timer;
void test_thread(void *args,unsigned long signal)
{
	if(signal)	{
		printk("\nTest thread signalled!");
		update_timer(&test_timer);
		return;
	}
	printk("\nTest thread!!");
	while(1);
}

void show_memory_stats()
{
	printk("\nMemory");
	printk("\nTotal:%d kB (%d B)",(sys_occ()+mem_occ())/1024,sys_occ()+mem_occ());
	printk("\nSystem:%d kB (%d B)",sys_occ()/1024,sys_occ());
	printk("\nSystem allocations:%d kB (%d B)",mem_occ()/1024,mem_occ());
}


void cl()
{
	char *inp,*param,*param1;
	struct object *cur,*x;
	struct data *d,*cur_data=NULL;
	struct link *cur_link=NULL;
	unsigned long cpid,tpid;
	int i;
	printk("\nCreating RP system");
	init_dt_reg();
	cur=init_sys();
	inp=(char *)malloc(USR_INP*sizeof(char));
	param=(char *)malloc(USR_INP*sizeof(char));
	param1=(char *)malloc(USR_INP*sizeof(char));
	printk("\nFormat:[<object>/<data>/<link>]");
	stdgetch_prepare();
	disk=get_device("hddbios");
	init_rpsvm_commands();
	shell_start();
	while(1)	{
		display_object(cur);
		printk("\n[%s/%s/%s]",get_obj_desc(cur),cur_data ? get_data_desc(cur_data):"",cur_link ? get_obj_desc(cur_link->link_object) : "");
		gets(inp,USR_INP);
		getstringparameter(inp,param,' ',0);
		if(!strcmp(param,"help"))	{
			
		} else if(!strcmp(param,"linknew"))	{	//Create a link to the current object
			
		} else if(!strcmp(param,"linkopen"))	{	//Open a link for editing
			getstringparameter(inp,param,' ',1);
			for(i=0;i<MAX_LINK && cur->links[i];i++)	{
				if(!strcmp(param,get_obj_desc(cur->links[i]->link_object)))	{
					cur_link=cur->links[i];
					break;
				}
			}
		} else if(!strcmp(param,"linkdelete"))	{
			getstringparameter(inp,param,' ',1);
			for(i=0;i<MAX_LINK && cur->links[i];i++)	{
				if(!strcmp(param,get_obj_desc(cur->links[i]->link_object)))	{
					delete_link(cur,i);
					cur_link=NULL;
					break;
				}
			}
		} else if(!strcmp(param,"linkpass"))	{	//Edit the passed the parameters
			getstringparameter(inp,param,' ',1);
			make_linkpass(cur_link,get_data(param));
		} else if(!strcmp(param,"linktype"))	{	//Edit link type
			getstringparameter(inp,param,' ',1);
			for(i=0;i<LT_CNT;i++)	{
				if(!strcmp(param,LTT_usr[i]))	{
					(cur_link->link_type)&=~0x70;
					(cur_link->link_type)|=i<<4;
					break;
				}
			}
		} else if(!strcmp(param,"linkcondition"))	{	//Create a condition for the link
			getstringparameter(inp,param,' ',1);
			cur_link->c_dat1=get_data(param);
			getstringparameter(inp,param,' ',2);
			for(i=0;i<CON_CNT;i++)	{
				if(!strcmp(param,CON_usr[i]))	{
					cur_link->c_type=i;
					break;
				}
			}
			getstringparameter(inp,param,' ',3);
			if(param[0]=='0')	{
				cur_link->link_type|=LT_CONST;	
				/*Link type classification to indicate that c_dat2 is actually a constant to be compared with and not a structure pointer*/
				cur_link->c_dat2=(struct data *)getnumber(param);
			} else	{
				cur_link->c_dat2=get_data(param);
			}
			cur_link->link_type|=LT_C;	/*Make the link conditional now*/
		} else if(!strcmp(param,"new"))	{	//Create a new object
			getstringparameter(inp,param,' ',1);
			x=create_object();
			register_object(x,param);
		} else if(!strcmp(param,"ls"))	{	//List objects
			printk("\nRegistered objects:");
			display_list();
		} else if(!strcmp(param,"open"))	{	//Open an object
			getstringparameter(inp,param,' ',1);
			cur=get_object(param);
			cur_link=NULL;
		} else if(!strcmp(param,"datanew"))	{	//Create data
			getstringparameter(inp,param,' ',1);
			d=create_data(cur);
			register_data(d,cur,param);
			cur_data=d;
		} else if(!strcmp(param,"show"))	{	//Show the details of the current object
			display_object(cur);
		} else if(!strcmp(param,"datals"))	{	//List all the data registered
			display_vlist();
		} else if(!strcmp(param,"dataopen"))	{	//Open data for editing
			getstringparameter(inp,param,' ',1);
			cur_data=get_data(param);
		} else if(!strcmp(param,"datanewchild"))	{	//Create data as child member of the current data opened
			getstringparameter(inp,param,' ',1);
			d=create_child_data(cur_data);
			register_data(d,cur,param);
			cur_data=d;
		} else if(!strcmp(param,"dataclose"))	{	//Close data.
			cur_data=NULL;
		} else if(!strcmp(param,"linkclose"))	{	//Close link
			cur_link=NULL;
		} else if(!strcmp(param,"datastr"))	{	//Make the data a string
			cur_data->d_type=DT_STRING;
			getstringenv(inp,param,'(',')');
			cur_data->d_len=strlen(param)+1;
			cur_data->x=(void *)malloc(strlen(param)+1);
			strcpy(cur_data->x,param);
			make_constructor(cur_data);
		} else if(!strcmp(param,"datanum"))	{	//Make the data a number
			cur_data->d_type=DT_INT;
			cur_data->d_len=sizeof(int);
			cur_data->x=(void *)getparam(inp,' ',1);
			make_constructor(cur_data);
		} else if(!strcmp(param,"lsdt"))	{
			list_dt_reg();
		} else if(!strcmp(param,"control"))	{	//Start execution
			cpid=create_thread("control_rps",control_rps,get_object("sys"),NULL);
		} else if(!strcmp(param,"controlend"))	{	//End execution
			delete_thread(cpid);
		} else if(!strcmp(param,"mem"))	{	//Show system memory usage details
			show_memory_stats();
		} else if(!strcmp(param,"rset"))	{	//Read a setting
			getstringparameter(inp,param,' ',1);
			unsigned val;
			char *str;
			val=read_setting_val(param);
			str=read_setting_str(param);
			printk("\n%s:%d,%s",param,val,str? str:"");
		}  else if(!strcmp(param,"wset"))	{	//Write a setting
			getstringparameter(inp,param,' ',1);
			getstringparameter(inp,param1,' ',2);
			if(param1[0]=='0')
				write_setting_val(param,getnumber(param1));
			else
				write_setting_str(param,param1);
		} else if(!strcmp(param,"lsset"))	{	//List settings
			list_settings();
		} else if(!strcmp(param,"ui"))	{	//Start stupid gui
			init_ui(getparam(inp,' ',1),getparam(inp,' ',2),0);
		} else if(!strcmp(param,"cls"))	{
			clrscr();
		} else if(!strcmp(param,"lsthread"))	{
			list_threads();
		} else if(!strcmp(param,"ntfs"))	{
			ntfs_detect(getparam(inp,' ',1));
		} else {
			printk("\nCannot find this command");
		}
	}
}
